﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;
using System.Runtime.Serialization.Formatters;

namespace TPOJ.MSMQMessaging
{
    public class TPOJQueue : IDisposable 
    {
        protected MessageQueueTransactionType transactionType = MessageQueueTransactionType.Automatic;
        protected MessageQueue queue;
        protected TimeSpan timeout;

        public TPOJQueue(string queuePath, int timeoutSeconds)
        {
            queue = new MessageQueue(queuePath);
            
            timeout = TimeSpan.FromSeconds(Convert.ToDouble(timeoutSeconds));

            // Performance optimization since we don't need these features
            queue.DefaultPropertiesToSend.AttachSenderId = false;
            queue.DefaultPropertiesToSend.UseAuthentication = false;
            queue.DefaultPropertiesToSend.UseEncryption = false;
            queue.DefaultPropertiesToSend.AcknowledgeType = AcknowledgeTypes.None;
            queue.DefaultPropertiesToSend.UseJournalQueue = false;
        }

        public virtual object ReceiveMessage()
        {
            try
            {
                using (Message message = queue.Receive(timeout, transactionType))
                {
                    message.Formatter = new XmlMessageFormatter(new Type[] { typeof(TPOJ.Model.Message) });
                    return message;
                }
            }
            catch (MessageQueueException mqex)
            {
                if (mqex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout)
                    throw new TimeoutException();
                throw;
            }
        }

        public virtual void SendMessage(object msg)
        {
            try
            {
                queue.Send(msg, transactionType);
            }
            catch(Exception ex)
            {
                ex.ToString();
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            queue.Dispose();
        }

        #endregion
    }
}
